package eu.gline.km.server;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.util.logging.Level;

import eu.gline.km.jni.keyboard.Keyboard_simulator;
import eu.gline.km.jni.mouse.Mouse_simulator;
import eu.gline.km.protocol.PROTOCOL;

public class KmClient extends Thread {
	
	private KmServer kms;
	private Socket socket;
	private DataInputStream dis;
	@SuppressWarnings("unused")
	private DataOutputStream dos;
	
	private Keyboard_simulator ks;
	private Mouse_simulator ms;
	
	public KmClient(KmServer kms, Socket s) {
		this.kms = kms;
		socket = s;
		ks = new Keyboard_simulator();
		ms = new Mouse_simulator();
		
		try {
			dis = new DataInputStream(s.getInputStream());
			dos = new DataOutputStream(s.getOutputStream());
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public void run() {		
		kms.getLogger().log(Level.FINER, "Client started: " + socket.getInetAddress().getHostName());
		
		try {
			int iread;
		
			while ((iread = dis.readInt())!=-1) {
				
				// debug
				kms.getLogger().log(Level.FINEST, "Incoming type from " + socket.getInetAddress().getHostName() + " -> " + iread);				
				
				switch (iread) {
					case PROTOCOL.Test:
						System.out.println("ok");
						break;
					case PROTOCOL.Keyboard:
						int param1 = dis.readInt();
						int param2 = dis.readInt();
						kms.getLogger().log(Level.FINEST, "Keyboard event - parameter1 is " + param1 + " - parameter2 is " + param2);
						if (param1 >= 0x00 && param1 <= 0xFF && param2 >= 0x0000 && param2 <= 0x0004) {
							ks.Keybd_event(param1, param2);
						}
						break;
					case PROTOCOL.SetForegroundWindow:
						String window = dis.readUTF();
						kms.getLogger().log(Level.FINEST, "SetForegroundWindow event - parameter is " + window);
						if (window != null) ks.SetForegroundWindow(window);
						break;
						
					case PROTOCOL.MousePos:
						int x = dis.readInt();
						int y = dis.readInt();
						kms.getLogger().log(Level.FINEST, "MousePos event - x is " + x + " - y is " + y);
						if (x <= 20000 && y <= 20000) {
							ms.SetCursorPos(x, y);
						}
						break;
					case PROTOCOL.MouseUp:
						int x2 = dis.readInt();
						kms.getLogger().log(Level.FINEST, "MouseUp event - parameter is " + x2);
						if (x2 <= 20000) {
							ms.CursorUp(x2);
						}
						break;
					case PROTOCOL.MouseDown:
						int x3 = dis.readInt();
						kms.getLogger().log(Level.FINEST, "MouseDown event - parameter is " + x3);
						if (x3 <= 20000) {
							ms.CursorDown(x3);
						}
						break;
					case PROTOCOL.MouseLeft:
						int x4 = dis.readInt();
						kms.getLogger().log(Level.FINEST, "MouseLeft event - parameter is " + x4);
						if (x4 <= 20000) {
							ms.CursorLeft(x4);
						}
						break;
					case PROTOCOL.MouseRight:
						int x5 = dis.readInt();
						kms.getLogger().log(Level.FINEST, "MouseRight event - parameter is " + x5);
						if (x5 <= 20000) {
							ms.CursorRight(x5);
						}
						break;
					case PROTOCOL.MouseEvent:
						int mevent = dis.readInt();
						int mx = dis.readInt();
						int my = dis.readInt();
						int mdata = dis.readInt();
						kms.getLogger().log(Level.FINEST, "MouseEvent event - parameter1 is " + mevent
								+ " - parameter2 is " + mx
								+ " - parameter3 is " + my
								+ " - parameter4 is " + mdata
							);
						if (mevent >= 0x0000 && mevent <= 0x8000
								&& mx <= 20000
								&& my <= 20000
								&& mdata <= 2000) {
							ms.Mouse_event(mevent, mx, my, mdata);
						}
						break;
					default:
						kms.getLogger().log(Level.WARNING, "Unknown incoming event: " + iread);
				}
				
			}
			
			
		} catch (IOException e) {
			kms.removeClient(this);
		}
		
	}
	
	public Socket getSocket() {
		return socket;
	}

}
